/**
 * GraphicUtils.java
 *  
 * @author Beatrice Bacelli
 * @author Luca Bedogni
 * @author Silvia Righini
 */
package unibo.lsb.graphic;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import unibo.lsb.communication.CommunicationLocal;
import unibo.lsb.communication.InformationSingleton;
import unibo.lsb.logic.PlayerSelf;
import unibo.lsb.logic.PlayerSelfSingleton;
import unibo.lsb.logic.PlayersTable;

/**
 * Class to hold some utility methods
 */
public class GraphicUtils {

	public static final int DO_NOTHING_ON_CLOSE = 0;
	/**
	 * Closes the frame that called the dialog.
	 */
	public static final int BACK_TO_MAIN_ON_CLOSE = 1;

	/**
	 * Constructor
	 */
	GraphicUtils() {

	}

	/**
	 * An error dialog box is displayed
	 * 
	 * @param component
	 *            component to anchor the dialog box to
	 * @param msg
	 *            message to display
	 * @param title
	 *            title of the dial
	 * @param msgType
	 *            can be one among: {@link JOptionPane#ERROR_MESSAGE},
	 *            {@link JOptionPane#PLAIN_MESSAGE},
	 *            {@link JOptionPane#INFORMATION_MESSAGE},
	 *            {@link JOptionPane#QUESTION_MESSAGE}
	 */
	public static void displayDialog(JFrame frame, String msg, String title,
			int msgType, int operationOnClose) {
		if (frame != null) {
			if ((msgType != JOptionPane.ERROR_MESSAGE)
					&& (msgType != JOptionPane.PLAIN_MESSAGE)
					&& (msgType != JOptionPane.QUESTION_MESSAGE)
					&& (msgType != JOptionPane.INFORMATION_MESSAGE)) {
				msgType = JOptionPane.PLAIN_MESSAGE;
			}
			JOptionPane.showMessageDialog(frame, msg, title, msgType);
			if (operationOnClose == DO_NOTHING_ON_CLOSE) {
			} else if (operationOnClose == BACK_TO_MAIN_ON_CLOSE) {
				frame.setVisible(false);
				MainWindowSingleton.getInstance().getMainWindow().setVisible(
						true);
			}
		} else {
			System.err
					.println("Not showing dialog window, passed component is null");
		}
	}

	/**
	 * Returns a buffered image located at given path. Displays an error in the
	 * stderr and returns null if the image is not found.
	 * 
	 * @param path
	 * @return
	 */
	public BufferedImage getImage(String path) {
		BufferedImage sourceImage = null;
		try {
			URL url = getClass().getResource(path);
			if (url == null) {
				System.err.println("Can't find location: " + path);
			}
			sourceImage = ImageIO.read(url);
		} catch (IOException e) {
			System.err.println("Failed to load image at: " + path);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sourceImage;
	}

	/**
	 * Returns the icon with number ( i.e. filename) n.
	 * 
	 * @param n
	 *            the number/filename of the icon
	 * @return
	 */
	public Icon getDiceIcon(int n) {
		String dieLocalPath = ConfigurationConstGraphics.DIEF_PATH + n
				+ ConfigurationConstGraphics.DIEF_EXT;
		URL dieUrl = getClass().getResource(dieLocalPath);
		return new ImageIcon(dieUrl);
	}

	/**
	 * Returns true if only one last player alive and without the maximum number
	 * of penalties is found.
	 * 
	 * @return
	 */
	public static boolean checkLastAlive() {
		boolean b = false;
		PlayersTable pt = InformationSingleton.getInstance().getpt();
		int n = pt.checkLastOneStanding();
		PlayerSelf self = PlayerSelfSingleton.getInstance().getSelf();
		int mypenalties = pt.getPlayer(self.getIndexInTable()).getPenalty();

		// everyone lost
		if (n == PlayersTable.PLAYERS_ALL_LOSE) {
			// no player, including myself, is alive or with less than
			// MAX_PENALTY
			GameTableWindow gt = GameTableWindowSingleton.getInstance()
					.getGameTablePanel();
			gt.refreshPanels();
			displayDialog(gt, MessagesGenerator.everyoneLost(),
					MessagesGenerator.gameOver(), JOptionPane.PLAIN_MESSAGE,
					BACK_TO_MAIN_ON_CLOSE);
			GameTableWindowSingleton.closeGame();
		} else if (n == PlayersTable.PLAYERS_LOT_ALIVE) {
			b = false;
			// I wait for someone to talk to me
		} else if (n == PlayersTable.PLAYERS_ALL_DEAD_BUT_ME) {
			GraphicUtils.displayDialog(GameTableWindowSingleton.getInstance()
					.getGameTablePanel(), MessagesGenerator.youWin(),
					MessagesGenerator.gameOver(), JOptionPane.PLAIN_MESSAGE,
					GraphicUtils.BACK_TO_MAIN_ON_CLOSE);
			GameTableWindowSingleton.closeGame();
			b = true;
		} else if (n >= 0) {
			if (self.equals(pt.getPlayer(n).getPlayerId())) {
				// the last player standing is me! I tell myself and everyone
				// else I won..
				if (mypenalties < PlayersTable.MAX_PENALTIES) {
					GraphicUtils.displayDialog(GameTableWindowSingleton
							.getInstance().getGameTablePanel(),
							MessagesGenerator.youWin(), MessagesGenerator
									.gameOver(), JOptionPane.PLAIN_MESSAGE,
							GraphicUtils.BACK_TO_MAIN_ON_CLOSE);
					CommunicationLocal.notifyWinning(self.getIndexInTable());
				} else {
					GraphicUtils.displayDialog(GameTableWindowSingleton
							.getInstance().getGameTablePanel(),
							MessagesGenerator.everyoneLost(), MessagesGenerator
									.gameOver(), JOptionPane.PLAIN_MESSAGE,
							GraphicUtils.BACK_TO_MAIN_ON_CLOSE);
					CommunicationLocal.notifyWinning(self.getIndexInTable());
				}
				GameTableWindowSingleton.closeGame();
			} else {
				// the last player standing is not me
				if (mypenalties >= PlayersTable.MAX_PENALTIES) {
					// Ok, I am not standing because I am out of penalties
					// I wait
				} else {
					System.err.println("How come?! A last one standing ("
							+ n
							+ ") and it's not me! (I am "
							+ PlayerSelfSingleton.getInstance().getSelf()
									.getIndexInTable() + " and I only have "
							+ mypenalties + " penalties).");
				}
			}
			b = true;
		} else {
			// PlayersTable.checkLastOneStanding error
		}
		return b;
	}
}
